﻿using DapperExtensions;
using Dm;
//using IBM.Data.Db2;
using Kdbndp;
using Microsoft.Data.SqlClient;
using Microsoft.Data.Sqlite;
using MySql.Data.MySqlClient;
using Npgsql;
using Oracle.ManagedDataAccess.Client;
using System.ComponentModel.DataAnnotations;
using System.Data.Common;

namespace DoNet.ORM.Repository.Repository
{
    /// <summary>
    /// 注册方式‌：
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class DapperRepository : IRepository
    {
        /// <summary>
        /// 
        /// </summary>
        [Required]
        private readonly DbConnection _db;
        /// <summary>
        /// 
        /// </summary>
        private DbTransaction? _transaction = null;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="connectionString"></param>
        public DapperRepository(DataBaseType dataBaseType, string connectionString)
        {
             _db = dataBaseType switch
             {
                 DataBaseType.MySql => new MySqlConnection(connectionString),
                 DataBaseType.SqlServer => new SqlConnection(connectionString),
                 DataBaseType.Sqlite => new SqliteConnection(connectionString),
                 DataBaseType.Oracle => new OracleConnection(connectionString),
                 DataBaseType.PostgreSQL => new NpgsqlConnection(connectionString),
                 DataBaseType.Dm => new DmConnection(connectionString),
                 DataBaseType.Kdbndp => new KdbndpConnection(connectionString),
                 //DataBaseType.DB2 => new DB2Connection(connectionString),
                 _ => throw new ArgumentOutOfRangeException("不支持的数据库类型！")
             };
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public long Insert<T>(T entity) where T : class, new()
        {
            return _db.Insert(entity);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<long> InsertAsync<T>(T entity) where T : class, new()
        {
            return await _db.InsertAsync(entity);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public long Update<T>(T entity) where T : class, new()
        {
            return _db.Update(entity);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<long> UpdateAsync<T>(T entity) where T : class, new()
        {
            return await _db.UpdateAsync(entity);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public long Delete<T>(T entity) where T : class, new()
        {
            return _db.Delete(entity);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<long> DeleteAsync<T>(T entity) where T : class, new()
        {
            return await _db.DeleteAsync(entity);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public IEnumerable<T> GetAll<T>() where T : class, new()
        {
            return _db.GetList<T>();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public async Task<IEnumerable<T>> GetAllAsync<T>() where T : class, new()
        {
            return await _db.GetListAsync<T>();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T? GetById<T>(long id) where T : class, new()
        {
            return _db.Get<T>(id);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<T?> GetByIdAsync<T>(long id) where T : class, new()
        {
            return await _db.GetAsync<T>(id);
        }

        #region 事务
        /// <summary>
        /// 同步开启事务
        /// </summary>
        public void BeginTransaction()
        {
            _transaction = _db.BeginTransaction();
        }
        /// <summary>
        /// 同步提交事务
        /// </summary>
        public void CommitTransaction()
        {
            if (_transaction != null)
                _transaction.Commit();
        }
        /// <summary>
        /// 同步回滚事务
        /// </summary>
        public void RollbackTransaction()
        {
            if (_transaction != null)
                _transaction.Rollback();
        }
        /// <summary>
        /// 异步开启事务
        /// </summary>
        public async Task BeginTransactionAsync()
        {
            _transaction = await _db.BeginTransactionAsync();
        }
        /// <summary>
        /// 异步提交事务
        /// </summary>
        public async Task CommitTransactionAsync()
        {
            if (_transaction != null)
                await _transaction.CommitAsync();
        }
        /// <summary>
        /// 异步回滚事务
        /// </summary>
        public async Task RollbackTransactionAsync()
        {
            if (_transaction != null)
                await _transaction.RollbackAsync();
        }
        #endregion 事务
    }
}
